from datetime import datetime

from captcha.models import CaptchaStore
from django.shortcuts import render
from django.conf import settings
from rest_framework.exceptions import APIException
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet

from Apps.util.jwt_util import JwtToken_create
from Apps.util.request_util import get_request_ip, get_login_location, get_browser, get_os, get_device, get_weather, \
    get_day_note
from Apps.System.models import SystemUserLoginInfo
from Apps.User.models import User
from Apps.User.userSer import UserSer, PostUserSer

from Apps.common.response import SuccessResponse, ErrorResponse


class CheckUserView(APIView):
    def get(self, request, *args, **kwargs):
        return SuccessResponse("成功")


class GetUserView(ModelViewSet):
    authentication_classes = []
    queryset = User.objects.all()
    serializer_class = UserSer


class PostUserView(ModelViewSet):
    authentication_classes = []
    queryset = User.objects.all()
    serializer_class = PostUserSer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return SuccessResponse(serializer.data)


class LoginView(APIView):
    authentication_classes = []

    def code(self, request):

        if not settings.CAPTCHA_STATE:  # 未开启验证码则返回 True
            return True
        codeKey = request.data.get('codeKey', None)
        code = request.data.get('code', None)
        if not code:
            raise APIException(detail='无验证码')
        try:
            get_captcha = CaptchaStore.objects.get(hashkey=codeKey)
            if str(get_captcha.response).lower() == code.lower():  # 如果验证码匹配
                get_captcha.delete()
                return True
            # 开放code，方便测试
            if code.lower() == "789":
                if get_captcha:
                    get_captcha.delete()
                return True

            else:
                # 验证失败情况，删除数据库code
                if get_captcha:
                    get_captcha.delete()
                raise APIException(detail='验证码错误')
        except Exception:
            raise APIException(detail='验证码错误')

    def post(self, request, *args, **kwargs):
        # 校验验证码
        if not self.code(request):
            return ErrorResponse("验证码错误")

        # 校验用户名，密码
        username = request.data["username"]
        password = request.data["password"]
        try:
            if username == '' or password == '':
                raise ValueError("用户名或密码为空")
            user = User.objects.filter(username=username).first()
            if user is not None:
                check_result = user.check_password(password)
                if check_result:
                    user.last_login = datetime.now()
                    user.save()

                    token = JwtToken_create(user)

                    self.sava_login_info(request, user.id, username,
                                         msg="登陆系统", login_type="密码登陆", status='登陆成功',
                                         losePassword=password)

                    return SuccessResponse(
                        # data={"user": user.username, "token": token, "role": user.roles, "menu": ""},
                        data={"userid": user.id, "user": user.username, "token": token},
                        message="登陆成功")
        except ValueError as e:
            pass

        self.sava_login_info(request, "", username,
                             msg="登陆系统", login_type="密码登陆", status='登陆失败',
                             losePassword=password)
        return ErrorResponse(msg="登陆失败")

    def sava_login_info(self, request, userId, username, msg, login_type, status, losePassword):
        browser = get_browser(request)
        ipaddr = get_request_ip(request)
        device = get_device(request)
        os = get_os(request)
        location = get_login_location(request)

        login_info = SystemUserLoginInfo(userid=userId, username=username, browser=browser, ipaddr=ipaddr,
                                         device=device,
                                         loginLocation=location, msg=msg, os=os, status=status,
                                         login_type=login_type, losePassword=losePassword)
        login_info.save()
